package com.hevery.beans.factory;

import com.hevery.beans.BeanDefinition;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: BeanFactory 的一种抽象类实现，规范了 IoC 容器的基本结构，
 * 但是把生成 Bean 的具体实现方式留给子类实现。IoC 容器的结构：AbstractBeanFactory
 * 维护一个 beanDefinitionMap 哈希表用于保存类的定义信息（BeanDefinition）。
 * 获取 Bean 时，如果 Bean 已经存在于容器中，则返回之，否则则调用 doCreateBean
 * 方法装配一个 Bean。（所谓存在于容器中，是指容器可以通过 beanDefinitionMap 获取
 * BeanDefinition 进而通过其 getBean() 方法获取 Bean。）
 * @author: hongyu.zhang
 * @create: 2018-03-20
 **/
public abstract class AbstractBeanFactory implements BeanFactory{

    /** key是xml中的name值，value是对应的beanDefinition*/
    private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();

    /**
     * 根据名字获取bean实例(实例化并初始化bean)
     * @param name
     * @return
     */
    @Override
    public Object getBean(String name){
        //已经注册到ConcurrentHashMap中的BeanDefinition(Bean)
        return beanDefinitionMap.get(name).getBean();
    }

    /**
     * 向beanDefinitionMap中注册BeanDefinition
     * @param name
     * @param beanDefinition
     * @throws Exception
     */
    @Override
    public void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception {
        Object bean = doCreateBean(beanDefinition);
        beanDefinition.setBean(bean);
        beanDefinitionMap.put(name,beanDefinition);
    }

    abstract Object doCreateBean(BeanDefinition beanDefinition)throws Exception;
}
